
import java.io.*;
import java.util.*;
import java.text.*;

public class SolitaireBattleship
{
    public String name;
    public final Board board;
    public final Ship[] availableShips;
    
    //Reads the input file and creates the board and the ships
    public SolitaireBattleship() throws java.io.IOException
    {
        String line;
        String delim = "[ ]+";
        String[] tokens;
        
        int boardLength;
        int boardWidth;
        int shipLength;
        int count;

        name = "Solitaire Battleship Problem";

        //Read the input data and create the Board and Ships
        BufferedReader input = new BufferedReader(new FileReader(Parameters.dataInputFileName));

        //Board Size
        line = input.readLine();
        tokens = line.split(delim);
        boardLength = Integer.parseInt(tokens[1]);
        boardWidth = Integer.parseInt(tokens[2]);
        
        //row and column target values
        List<Integer> rowTargetList = new ArrayList<Integer>();
        line = input.readLine();
        tokens = line.split(delim);
        
        for (int i=1; i<tokens.length; i++)
        {
        	rowTargetList.add(Integer.parseInt(tokens[i]));
        }
        
        List<Integer> columnTargetList = new ArrayList<Integer>();
        line = input.readLine();
        tokens = line.split(delim);
        
        for (int i=1; i<tokens.length; i++)
        {
        	columnTargetList.add(Integer.parseInt(tokens[i]));
        }
        
        this.board = new Board(boardLength, boardWidth, columnTargetList, rowTargetList);

        //Ships
        List<Ship> ships = new ArrayList<Ship>();
        while ((line = input.readLine()) != null && line.length() > 0) {
            tokens = line.split(delim);
            shipLength = Integer.parseInt(tokens[0]);
            count = Integer.parseInt(tokens[1]);

            for (int i = 0; i < count; i++) {
                ships.add(new Ship(shipLength));
            }
        }
        availableShips = ships.toArray(new Ship[ships.size()]);
        
        input.close();
    }

    public Ship[] getCopyOfShips()
    {
        return availableShips.clone();
    }

    public Ship[] getDeepCopyOfShips()
    {
    	return SolitaireBattleship.getDeepCopyOfShips(availableShips);
    }
    
    public static Ship[] getDeepCopyOfShips(Ship[] ships)
    {
    	Ship[] deepCopyArray = new Ship[ships.length];
    	
    	for (int i=0; i<ships.length; i++)
    	{
    		deepCopyArray[i] = new Ship(ships[i]);
    	}
    	
        return deepCopyArray;
    }
    
    public void doRawFitness(Individual X, int level)
    {
    	//Fitness at the max level of difficulty
        X.rawFitness = board.getRawFitness(X.getShips());
        
        //Fitness at the current level of difficulty
        X.dynamicFitness = board.getDynamicFitness(X.getShips(), level);
    }
    
    public void printIndividual(Individual X)
    {
        BoardResult boardResult = new BoardResult(X.getShips(), this.board, Integer.MAX_VALUE);
        
        System.out.println();
        System.out.println(boardResult.getPrintedBoard());
    }
    
    public int calculateDelta(Individual individual)
    {   
        return board.getDelta(individual.getShips());
    }
}
